package com.budwk.app.miniapp.controllers.admin;


import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.exception.ServiceException;

import com.budwk.app.miniapp.models.*;
import com.budwk.app.miniapp.models.dto.SqfwRallyDTO;
import com.budwk.app.miniapp.services.SqfwRallyService;

import com.budwk.app.miniapp.services.SqfwRallySignService;
import com.budwk.app.miniapp.services.WxUserService;
import com.budwk.app.miniapp.services.WxeventService;
import com.budwk.starter.common.exception.BaseException;
import com.budwk.starter.common.openapi.annotation.*;

import com.budwk.starter.common.page.Pagination;
import com.budwk.starter.common.result.Result;
import com.budwk.starter.email.EmailSendServer;
import com.budwk.starter.log.annotation.SLog;
import com.budwk.starter.security.utils.SecurityUtil;
import com.budwk.starter.websocket.publish.MessageSendServer;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang.time.DateUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.integration.jedis.pubsub.PubSubService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import org.nutz.json.Json;
import org.nutz.lang.Strings;
import org.nutz.mvc.annotation.*;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@IocBean
@At("/platform/miniapp/sqfwRally")
@ApiDefinition(tag = "微信小程序-社区活动")
@Slf4j
public class SqfwRallyController {
    @Inject
    private SqfwRallyService sqfwRallyService;

    @Inject
    private SqfwRallySignService sqfwRallySignService;

    @Inject
    private MessageSendServer messageSendServer;

    @Inject
    private WxeventService wxEventService;
    @Inject
    private WxUserService wxUserService;

    @Inject("taskQueryExecutor")
    private ThreadPoolExecutor taskQueryExecutor;

    @Inject
    private PubSubService pubSubService;
    @Inject
    private RedissonClient redissonClient;
    @Inject
    private Dao dao;

    @At("/createOne")
    @Ok("json")
    @POST
    @ApiOperation(name = "新增社区活动")
    @ApiResponses
    @SLog(tag = "新增社区活动", value = "${args[0].rallyName}")
    public  Result<?> createOne(@Param("..") SqfwRally sqfwRally) {
        SqfwRally r=sqfwRallyService.createOne(sqfwRally);
        return Result.success(r);
    }


    @At("/getListPage")
    @Ok("json:{dateFormat:'yyyy-MM-dd'}")
    @POST
    @ApiOperation(name = "获取社区活动分页")
    @ApiResponses
    @SLog(tag = "获取社区活动分页")
    public  Result<?> getListPage(@Param("..") SqfwRally sqfwRally) {
        Cnd cnd = Cnd.NEW();
        if(StrUtil.isNotBlank(sqfwRally.getCommunity())&&!sqfwRally.getCommunity().equals("直属")){
            SqlExpressionGroup e1 = Cnd.exps(SqfwRally::getCommunity,"=",sqfwRally.getCommunity());
            SqlExpressionGroup e2 = Cnd.exps(SqfwRally::getCommunity,"=","直属");
            cnd.and(e1.or(e2));
        }
        if(StrUtil.isNotBlank(sqfwRally.getCounty())&&!sqfwRally.getCounty().equals("直属")){
            SqlExpressionGroup e1 = Cnd.exps(SqfwRally::getCounty,"=",sqfwRally.getCounty());
            SqlExpressionGroup e2 = Cnd.exps(SqfwRally::getCounty,"=","直属");
            cnd.and(e1.or(e2));
        }
        if(StrUtil.isNotBlank(sqfwRally.getDistrict())&&!sqfwRally.getDistrict().equals("直属")){
            SqlExpressionGroup e1 = Cnd.exps(SqfwRally::getDistrict,"=",sqfwRally.getDistrict());
            SqlExpressionGroup e2 = Cnd.exps(SqfwRally::getDistrict,"=","直属");
            cnd.and(e1.or(e2));
        }
        SqlExpressionGroup e1 = Cnd.exps("rally_content_json ->>'activityPublishedOrNot'","=",1);
        SqlExpressionGroup e2 = Cnd.exps("jsonb_exists(rally_content_json, 'activityPublishedOrNot')","is", null);
        cnd.and(e1.or(e2)).orderBy(SqfwRally::getCreateTime,"desc");
        Pagination r=sqfwRallyService.listPage(sqfwRally.getPageNo(),sqfwRally.getPageSize(), cnd);
        return Result.success(r);
    }


    @At("/getOne")
    @Ok("json")
    @POST
    @ApiOperation(name = "新增社区活动")
    @ApiResponses
    @SLog(tag = "获取社区活动", value = "${args[0].rallyName}")
    public  Result<?> getOne(@Param("..") SqfwRally sqfwRally) {
        SqfwRally r=sqfwRallyService.getOne(sqfwRally.getId());
        return Result.success(r);
    }

    @At("/getOneInfo")
    @Ok("json:{dateFormat:'yyyy-MM-dd'}")
    @POST
    @ApiOperation(name = "新增社区活动")
    @ApiResponses
    @SLog(tag = "获取社区活动", value = "${args[0].rallyName}")
    public  Result<?> getOneInfo(@Param("..") SqfwRally sqfwRally) {
        SqfwRally r=sqfwRallyService.getOneInfo(sqfwRally.getId());
        return Result.success(r);
    }

    @At("/updateOne")

    @Ok("json")
    @POST
    @ApiOperation(name = "修改社区活动")
    @ApiResponses
    @SLog(tag = "修改社区活动", value = "${args[0].rallyName}")
    public  Result<?> updateOne(@Param("..") SqfwRally sqfwRally) {
        sqfwRallyService.updateIgnoreNull(sqfwRally);
        return Result.success();
    }

    @At("/finishService")
    @Ok("json")
    @POST
    @ApiOperation(name = "完结任务")
    @SLog(tag = "完结社区活动", value = "${args[0].rallyName}")
    @ApiResponses
    public Result<?> finishService(@Param("..") SqfwRally sqfwRally) {
        sqfwRallyService.finishService(sqfwRally.getId());
        return Result.success();
    }

    @At("/delRally")
    @Ok("json")
    @POST
    @ApiOperation(name = "完结任务")
    @SLog(tag = "删除社区活动", value = "${args[0].rallyName}")
    @ApiResponses
    public Result<?> delRally(@Param("..") SqfwRally sqfwRally) {
        System.out.println(sqfwRally.getId());
        sqfwRallyService.delOne(sqfwRally.getId());
        return Result.success();
    }


    @At("/singUp")
    @Ok("json")
    @POST
    @ApiOperation(name = "参加活动")
    @SLog(tag = "参加活动", value = "${id}")
    @ApiResponses
    public Result<?> singUp(@Param("..") SqfwRallySign rallySign) {
        List<SqfwCenSusPaper> sqfwCenSusPapers= sqfwRallyService.singUp(rallySign);
        if(CollectionUtil.isEmpty(sqfwCenSusPapers)){
            return  Result.success();
        }else {
            return  Result.success(1,"您的姓名与其他人相同，请选择您的出生日期。");
        }
    }

    @At("/checkToken")
    @Ok("json")
    @GET
    @SaCheckLogin
    public Result<?> checkToken() {
        return Result.success();
    }

    @At("/getJoinUser")
    @Ok("json:{dateFormat:'yyyy-MM-dd'}")
    @POST
    @ApiOperation(name = "报名人员列表")
    @ApiResponses
    public Result<?> getJoinUser(@Param("..") SqfwRally sqfwRally) {
        SqfwRally rally = sqfwRallyService.fetch(sqfwRally.getId());
        if(ObjectUtil.isEmpty(rally)){
            throw new ServiceException("无法找到对象");
        }
       List<SqfwRallySign> r= sqfwRallySignService.query(Cnd.where(SqfwRallySign::getRallyId,"=",sqfwRally.getId()));
       if(CollUtil.isNotEmpty(r)){
           r.forEach(s->{
               s.setRallyName(rally.getRallyName());
               s.setDept(rally.getRallyReleaseDept());
               if(Validator.isCitizenId(s.getCardId())) {
                   int age= IdcardUtil.getAgeByIdCard(s.getCardId());
                   s.setAge(age);
               }
           });
       }else {
           SqfwRallySign rallySign=new SqfwRallySign();
           r.add(rallySign);
       }
       return Result.success(r);
    }

    @At("/mineRally")
    @Ok("json:{dateFormat:'yyyy-MM-dd'}")
    @GET
    @ApiOperation(name = "我的报名")
    @SaCheckLogin
    public Result<?> mineRally() {
        WxUser wxUser = wxUserService.fetch(SecurityUtil.getUserId());
        List<SqfwRallySign> sqfwRallySigns = sqfwRallySignService.query(Cnd.where(SqfwRallySign::getPhone,"=",wxUser.getPhone())
                .desc(SqfwRallySign::getCreateDate));
        //Map<String,SqfwRallySign> stringSqfwRallySignMap=sqfwRallySigns.stream().collect(Collectors.toMap(SqfwRallySign::getRallyId,SqfwRallySign->SqfwRallySign ));
        List<String> rallyIds = sqfwRallySigns.stream().map(SqfwRallySign::getRallyId).collect(Collectors.toList());
        List<SqfwRally> sqfwRallies= sqfwRallyService.query(Cnd.where("id","in",rallyIds));
        if(CollectionUtil.isEmpty(sqfwRallies)){
            throw new BaseException("暂无数据");
        }
        Map<String,SqfwRally> stringSqfwRallyMap= sqfwRallies.stream().collect(Collectors.toMap(SqfwRally::getId,SqfwRally->SqfwRally ));
            List<SqfwRallyDTO> sqfwRallyDTOS=new ArrayList<>();
        sqfwRallySigns.forEach(s->{
            SqfwRallyDTO sqfwRallyDTO=new SqfwRallyDTO();
            sqfwRallyDTO.setId(s.getRallyId());
            sqfwRallyDTO.setSignId(s.getId());
            sqfwRallyDTO.setRallyName(stringSqfwRallyMap.get(s.getRallyId()).getRallyName());
            sqfwRallyDTO.setSignUpDate(s.getCreateDate());
            sqfwRallyDTO.setSignTimeoutFlag(DateUtil.compare(new Date(), DateUtils.addDays(stringSqfwRallyMap.get(s.getRallyId()).getRallyEndTime(),1)));
            sqfwRallyDTO.setName(s.getName());
            sqfwRallyDTOS.add(sqfwRallyDTO);
        });
        return Result.success(sqfwRallyDTOS);
    }
    @At("/cancelSingUp")
    @Ok("json")
    @POST
    @ApiOperation(name = "取消报名")
    @SaCheckLogin
    public Result<?> cancelSingUp(SqfwRallySign rallySign) {
        WxUser wxUser = wxUserService.fetch(SecurityUtil.getUserId());
        SqfwRallySign sqfwRallySign = sqfwRallySignService.fetch(Cnd.where(SqfwRallySign::getPhone,"=",wxUser.getPhone())
                .and(SqfwRallySign::getId,"=",rallySign.getId()));
        if(ObjectUtil.isNotEmpty(sqfwRallySign)){
            sqfwRallySignService.delete(rallySign.getId());
            return Result.success();
        }
       return Result.success("取消报名失败,无数据");

    }

    @At("/socketTest")
    @GET
    public void socketTest(@Param("id") String id,@Param("userId") String userId) {
        WxEvent wxEvent = wxEventService.fetch(id);
       // messageSendServer.wsSendMsg(userId, JSONUtil.toJsonStr(wxEvent));

    }



    @At
    @GET
    public void qpsTest() throws InterruptedException {
        RLock rLock = redissonClient.getLock("singUp:"+ 111);
        boolean lockFlag = rLock.tryLock(3, TimeUnit.SECONDS);
        System.out.println(lockFlag);
        rLock.unlock();
    }


//    @At("/sqlTest")
//    @GET
//    @Ok("json")
//    public Result<?> sqlTest() {
//        Sql sql = Sqls.create("select   distinct community as a1, county from shequ.sys_user sr where county  is not null and community is not null and (county !='直属' or community !='直属')");
//        sql.setCallback(Sqls.callback.entities());
//        sql.setEntity(dao.getEntity(Sys_user.class));
//        dao.execute(sql);
//        List<Sys_user> list = sql.getList(Sys_user.class);
//        return Result.success(list);
//
//    }
//
//
//
//
//    @At("/pubSubTest")
//    @GET
//    @Ok("json")
//    public Result<?> pubSubTest() {
//        Sql sql = Sqls.create("select   distinct community as a1, county from shequ.sys_user sr where county  is not null and community is not null and (county !='直属' or community !='直属')");
//        sql.setCallback(Sqls.callback.entities());
//        sql.setEntity(dao.getEntity(Sys_user.class));
//        dao.execute(sql);
//        List<Sys_user> list = sql.getList(Sys_user.class);
//        pubSubService.fire("wk:test:subscribe", Json.toJson(list));
//        return Result.success(list);
//
//    }
}
